package com.trendytech.tds.common.bean;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;

import com.trendytech.tds.common.mybatis.IPagination;

/**
 * 分页对象
 * @author lirui
 *
 */
//@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)
public class Pager<T> implements IPagination {
	
	public static final Integer MAX_PAGE_SIZE = 500;// 每页最大记录数限制

	public static final Integer DEFAULT_PAGE_SIZE = 10;// 每页默认记录数
	
	public static final Integer EXPORT_PAGE_SIZE = 100000;// daochu默认记录数数
	//界面模糊搜索输入框默认值
	public static final String DEAFULT_KEYWORD = "输入关键词";

	private Integer pageNumber = 1;// 当前页码
	private Integer pageSize = DEFAULT_PAGE_SIZE;// 每页记录数
	private int rowCount = 0;// 总记录数
	private Integer pageCount = 0;// 总页数
	private String property;// 查找属性名称
	private String keyword;// 查找关键字
	private Map<String, Object> parameters = new HashMap<String, Object>();// 查询参数
	private List<T> list;// 数据List
	private boolean isExport = false;

	private IPagerOrderFieldParser orderFieldParser;

	private SortProperty orderBy;

	private int startNum;
	private int endNum;
	/**
	 * 固定查询条件，逻辑删除标记为否
	 */
	private boolean invalid = false;
	
	private Set<SumProperty> sumFields;//合计字段集合，用于全部合计的查询
	
	private String businessCode;//业务编码
	/**
	 * 搜索引擎查询数据是否需要权限，默认true
	 */
	private boolean needPermission = true;
	/**
	 * 搜索引擎查询数据不需要权限时，是否在本公司内搜索，默认true，为否则在整个系统内搜索
	 */
	private boolean notNeedPermissionInCompany = true;
	
	/**
	 * 是否需要重建索引
	 */
	private boolean isReSolrIndex = false;
	
	@JsonIgnore
	public Integer getPageNumber() {
		return pageNumber;
	}

	public void setPageNumber(Integer pageNumber) {
		if (pageNumber < 1) {
			pageNumber = 1;
		}
		this.pageNumber = pageNumber;
	}

	@JsonIgnore
	public Integer getPageSize() {
		return getIsExport()?EXPORT_PAGE_SIZE:pageSize;
	}

	public void setPageSize(Integer pageSize) {
		if(pageSize == null){
			return;
		}
		if (pageSize < 1) {
			pageSize = 1;
		} else if(isExport){
			pageSize = EXPORT_PAGE_SIZE;
		}else if(pageSize > MAX_PAGE_SIZE) {
			pageSize = MAX_PAGE_SIZE;
		}
		this.pageSize = pageSize;
	}
	
	@JsonIgnore
	public int getRowCount() {
		return rowCount;
	}

	public void setRowCount(int totalCount) {
		this.rowCount = totalCount;
	}
	
	@JsonIgnore
	public Integer getPageCount() {
		pageCount = rowCount / pageSize;
		if (rowCount % pageSize > 0) {
			pageCount ++;
		}
		return pageCount;
	}

	public void setPageCount(Integer pageCount) {
		this.pageCount = pageCount;
	}
	@JsonIgnore
	public String getProperty() {
		return property;
	}

	public void setProperty(String property) {
		this.property = property;
	}

	@JsonIgnore
	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		this.keyword = StringUtils.trimToNull(keyword);
		if(DEAFULT_KEYWORD.equals(this.keyword)){
			this.keyword = null;
		}
	}

	@JsonIgnore
	public List<T> getList() {
		return list;
	}

	public void setList(List<T> list) {
		this.list = list;
	}
	@JsonIgnore
	public Map<String, Object> getParameters() {
		return parameters;
	}

	public void setParameters(Map<String, Object> parameters) {
		this.parameters = parameters;
	}
	@JsonIgnore
	public SortProperty getOrderByField() {
		if(orderBy == null){
			orderBy = buildOrderFieldParser().parseOrderField();
		}
		return orderBy;
	}
	@JsonIgnore
	public IPagerOrderFieldParser buildOrderFieldParser(){
		if(orderFieldParser == null){
			orderFieldParser = new DefaultPagerOrderFieldParser();
		}
		return orderFieldParser;
	}
	
	public void setOrderFieldParser(IPagerOrderFieldParser parser){
		orderFieldParser = parser;
	}
	@JsonProperty("totalRows")
	public int getTotal(){
		return rowCount;
	}
	@JsonProperty("table")
	public List<T> getData(){
		return list;
	}
	
	@JsonIgnore
	public int getStartNum() {
		return startNum;
	}

	public void setStartNum(int startNum) {
		this.startNum = startNum;
	}

	@JsonIgnore
	public boolean isInvalid() {
		return invalid;
	}

	public void setInvalid(boolean invalid) {
		this.invalid = invalid;
	}

	@JsonIgnore
	public boolean getIsExport() {
		return isExport;
	}

	public void setIsExport(boolean isExport) {
		this.isExport = isExport;
	}
	
	@JsonIgnore
	public Set<SumProperty> getSumFields() {
		return sumFields;
	}

	public void setSumFields(Set<SumProperty> sumFields) {
		this.sumFields = sumFields;
	}
	@JsonIgnore
	public String getBusinessCode() {
		return businessCode;
	}

	public void setBusinessCode(String businessCode) {
		this.businessCode = businessCode;
	}
	/**
	 * 搜索引擎查询数据是否需要权限，默认true
	 * @return
	 */
	@JsonIgnore
	public boolean isNeedPermission() {
		return needPermission;
	}

	public void setNeedPermission(boolean needPermission) {
		this.needPermission = needPermission;
	}
	/**
	 * 
	 * 搜索引擎是否需要重建索引，默认false
	 * @return
	 */
	@JsonIgnore
	public boolean isReSolrIndex() {
		return isReSolrIndex;
	}

	public void setReSolrIndex(boolean isReSolrIndex) {
		this.isReSolrIndex = isReSolrIndex;
	}
	/**
	 * 搜索引擎查询数据不需要权限时，是否在本公司内搜索，默认true，为否则在整个系统内搜索
	 * @return
	 */
	@JsonIgnore
	public boolean isNotNeedPermissionInCompany() {
		return notNeedPermissionInCompany;
	}

	/**
	 * 搜索引擎查询数据不需要权限时，是否在本公司内搜索，默认true，为否则在整个系统内搜索
	 * @param notNeedPermissionInCompany
	 */
	public void setNotNeedPermissionInCompany(boolean notNeedPermissionInCompany) {
		this.notNeedPermissionInCompany = notNeedPermissionInCompany;
	}
	@JsonIgnore
	public int getEndNum() {
		return endNum;
	}

	public void setEndNum(int endNum) {
		this.endNum = endNum;
	}
	
	/**
	 * Get page data from array
	 * @param arr
	 */
	public void setPageData(T[] arr) {
		if (arr == null) {
			return;
		}
		this.rowCount = arr.length;
		List<T> list = Arrays.asList(arr);
		int fromIndex = (this.pageNumber - 1) * this.pageSize;
		int toIndex = this.rowCount > (fromIndex + this.pageSize)
				? (fromIndex + this.pageSize) : this.rowCount;
		try {
			this.list = list.subList(fromIndex, toIndex);
		} catch (IndexOutOfBoundsException e) {
			throw new IndexOutOfBoundsException();
		}
	}
}
